#!/usr/bin/python
# -*- coding: utf-8 -*-
#创建SocketServerTCP服务器：

import socketserver as SocketServer
# from SocketServer import StreamRequestHandler

import os
import socket
import threading
import time
import json

# myname = socket.getfqdn(socket.gethostname())
# print(myname)
# myaddr = socket.gethostbyname(myname)

# print('selfip:%s,myname:%s'%(myaddr,myname))
# host = str(myaddr)

host = '192.168.8.155'  #这里是本机IP地址,运行后如果客户端连不上,注意一下是不是防火墙挡住了


port = 9101
addr = (host,port)


class MoveState(object):
    """docstring for MoveState"""
    def __init__(self, ):
        super(MoveState, self).__init__()
        #当前舵机状态，通过设备发送回的数据
        self.pwmST = {"1":0,"2":0,"3":0,"4":0,"5":0,"6":0}
        #当前新设置的状态
        self.pwmSet = {"1":0,"2":0,"3":0,"4":0,"5":0,"6":0}

        #当前动作状态，
        #-1,当前没有设备
        #0，当前没有新动作或动作已发送结束,
        #1.设置到绝对转动角度，
        #2.设置到相对转动角度(相对转到角度正为逆时针，负为顺时针方向),
        #3.保存当前转动角度为上电角度
        #4.设置转动角度时间序列动作
        #5.无条件停止当前动作
        #6.暂停动作
        #7.恢复暂停的动作，如果没有暂停动作，则这里不动作
        self.state = 0 

        self.deviceSocket = None   #设备的socket

        self.stepDatas = {}    #序列动作数据

    def stopMove(self):
        self.state = 5

    #设置一步序列动作
    def addStepData(self,num,data):
        self.state = 4
        self.stepDatas[str(num)] = data

    #清除之前序列动作中的一步
    def cleanOneStepData(self,num):
        self.stepDatas.pop(num)
        if not self.stepDatas:
            self.state = 0

    #清除所有序列数据
    def cleanAllStepData(self):
        self.state = 0
        self.stepDatas = {}

    #设备已连接
    def onDeviceConnect(self,dev):
        self.state = 0
        self.deviceSocket = dev

    def onMissDevice(self):
        self.cleanAllStepData()
        self.state = -1
        self.deviceSocket = None

    #设置某个舵机转动到angle角度
    def setPwmMove(self,num,angle):
        self.state = 1
        if num < 0:
            num = 0
        elif num > 5:
            num = 5
        tmpnum = num + 1
        self.pwmSet[str(tmpnum)] = angle

    #设置某个舵机转动相对角度
    def setPwmByMove(self,num,angle):
        self.state = 2
        if num < 0:
            num = 0
        elif num > 5:
            num = 5
        tmpnum = num + 1
        self.pwmSet[str(tmpnum)] += angle
        if self.pwmSet[str(tmpnum)] < 0:
            self.pwmSet[str(tmpnum)] = 0
        elif self.pwmSet[str(tmpnum)] > 180:
            self.pwmSet[str(tmpnum)] = 180

    #创建要发送给设备的json数据
    def makeSendData(self):
        #{"type":1,"data":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0}}
        dictmp = {}
        dictmp['type'] = self.state
        if self.state == 4:
            dictmp['data'] = self.stepDatas
        elif self.state == 1 or self.state == 2:
            dictmp['data'] = self.pwmSet
        elif self.state <= 0:
            print('设置state错误')
            return
        jstr = json.dumps(dictmp)
        return jstr

    def sendState(self):
        jstr = self.makeSendData()
        print(jstr)
        if self.deviceSocket:
            if type(jstr) == str:
                jstr = jstr.encode()
            self.deviceSocket.send(jstr)
            self.state = 0
        else:
            print('没有设备连接')

    def isHeaveClient(self):
        if self.deviceSocket:
            return True
        return False

moveobj = MoveState()

class Servers(SocketServer.StreamRequestHandler):
    def handle(self):
        print('got connection from ',self.client_address)
        while True:
            try:  
                data = self.request.recv(1024)
            except EOFError:  
                print('接收客户端错误，客户端已断开连接,错误码:')
                print(EOFError )
                moveobj.onMissDevice()
                break
            except:  
                print('接收客户端错误，客户端已断开连接')
                moveobj.onMissDevice()
                break
            if not data: 
                moveobj.onMissDevice()
                break
            # print('data len:%d'%(len(data)))
            # print("RECV from ", self.client_address)
            # print(data)
            moveobj.onDeviceConnect(self.request)
            # self.request.send('aaa')

#socket调用关闭clsoe()方法前要调用shutdown(2)方法来关闭socket通道
#SHUT_RD 关闭接收消息通道，SHUT_WR 关闭发送消息通道，SHUT_RDWR 两个通道都关闭。
#也就是说，想要关闭一个连接，首先把通道全部关闭，以上三个静态变量分别对应数字常量：0,1,2
#https://www.cnblogs.com/semishigure/p/7428945.html

def startServer(port = 9101,tmp = ''):
    server = SocketServer.ThreadingTCPServer(addr,Servers,bind_and_activate = False)
    server.allow_reuse_address = True   #设置IP地址和端口可以不使用客户端连接等待，并手动绑定服务器地址和端口，手动激活服务器,要不然每一次重启服务器都会出现端口占用的问题
    server.server_bind()
    server.server_activate()
    print('server started:')
    print(addr)
    server.serve_forever()
    
def start_serverThread():
    thr = threading.Thread(target=startServer,args=(port,'xxx'))
    thr.setDaemon(True)
    thr.start()

def main():
    start_serverThread()
    # ans = [0,15,30,45,60,75,90,75,60,45,30,15]
    ans = [0,15,30,45,60,75,90,75,60,45,30,15]
    while True:
        for n,k in enumerate(ans):
            for i in range(6):
                moveobj.setPwmMove(i, k)
            moveobj.sendState()
            time.sleep(3)
        
def initAll(ds):
    if ds:
        if len(ds) == 6:
            for i in range(6):
                moveobj.setPwmMove(i, ds[i])
            state = moveobj.sendState()
            time.sleep(1)

        elif type(ds) == int:
            for i in range(6):
                moveobj.setPwmMove(i, ds)
            moveobj.sendState()
            time.sleep(1)
    else:
        print("erro:not input data")

def getMoveObj():
    return moveobj

def test():
    start_serverThread()
    count = 0
    while not moveobj.isHeaveClient():
        count += 1
        print('没有设备连接，等3秒后重试,\n第%d次重试\n如果尝试100次后还是没有设备连接则程序自动退出...'%(count))
        time.sleep(3)
        if count >= 100:
            return
    initans = [90,90,90,90,90,90]
    initAll(initans)
    isNotEnd = True
    while isNotEnd:
        try:
            x = input("请输入多级编号和角度:")
            if len(x) !=2:
                continue
            num = x[0]
            ang = x[1]
            if num >= 0 and num <= 5:
                moveobj.setPwmMove(num, ang)
                moveobj.sendState()
                time.sleep(1)
        except Exception as e:
            print('输入参数错误\n')
        
def test2():
    a = [1,3,4]
    b = [1,3,4]
    if a == b:
        print('a=b')
    else:
        print('a!=b')

if __name__ == '__main__':
    # main()
    test2()